package com.dz.service.impl;

import com.alibaba.fastjson.JSON;
import com.dz.constant.JwtClaimsConstant;
import com.dz.constant.MessageConstant;
import com.dz.entity.User;
import com.dz.mapper.UserMapper;
import com.dz.properties.JwtProperties;
import com.dz.properties.WeChatProperties;
import com.dz.service.UserService;
import com.dz.utils.HttpClientUtil;
import com.dz.utils.JwtUtil;
import com.dz.vo.UserLoginVO;
import io.jsonwebtoken.lang.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author 鄧浩奇
 * @classname UserServiceImpl
 * @description
 * @since 2024/1/6 17:49
 **/

@Service
public class UserServiceImpl implements UserService {


    private final UserMapper userMapper;


    private final WeChatProperties weChatProperties;


    private final JwtProperties jwtProperties;


    @Autowired
    public UserServiceImpl(UserMapper userMapper, WeChatProperties weChatProperties, JwtProperties jwtProperties) {
        this.userMapper = userMapper;
        this.weChatProperties = weChatProperties;
        this.jwtProperties = jwtProperties;
    }

    /*
     * 微信登陆
     * */
    @Override
    public UserLoginVO wxLogin(String code) {
        // 微信登陆获取openID
        String openId = getOpenId(code);
        Assert.notNull(openId, MessageConstant.LOGIN_FAILED);
        // 判断数据库中有没有该用户
        User byOpenId = userMapper.selectByOpenId(openId);
        if (Objects.isNull(byOpenId)) {
            // 没有的话存入数据库
            User user = User.builder()
                    .openid(openId)
                    .build();
            userMapper.insert(user);
            byOpenId = user;
        }
        // 构造token
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.USER_ID, byOpenId.getId());
        String token = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), claims);
        // 封装vo返回
        return UserLoginVO.builder()
                .id(byOpenId.getId())
                .openid(openId)
                .token(token)
                .build();
    }

    /*
     * 获取用户信息
     * */
    @Override
    public User getUserById(Long userId) {
        User user = userMapper.selectById(userId);
        return Objects.isNull(user.getOpenid()) ? null : user;
    }


    private String getOpenId(String code) {
        // 拿到微信登陆的openid
        Map<String, String> paramMap = Map.of(
                "appid", weChatProperties.getAppid(),
                "secret", weChatProperties.getSecret(),
                "js_code", code,
                "grant_type", weChatProperties.getGrantType()
        );
        // Map.of()（Java 9 及更高版本）创建的是一个不可变的 Map 实例。一旦创建后，其内容不能被修改。试图修改它将抛出 UnsupportedOperationException 异常。
        String resp = HttpClientUtil.doGet("https://api.weixin.qq.com/sns/jscode2session", paramMap);
        return JSON.parseObject(resp).getString("openid");
    }
}
